package net.jxtz.jxtzos.authentication;


import lombok.extern.slf4j.Slf4j;
import net.jxtz.jxtzos.entity.auth.dto.RoleResourcesDto;
import net.jxtz.jxtzos.mapper.auth.RoleResourcesMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 * 封装过滤自定义资源权限类
 *
 * @author a123
 */
@Slf4j
@Component
public class MyFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

    @Override
    public Collection<ConfigAttribute> getAttributes(Object o) throws IllegalArgumentException {
        FilterInvocation filterInvocation = (FilterInvocation) o;
        final String requestUrl = filterInvocation.getRequestUrl();
        log.info("当前资源路径：" + requestUrl);
        if (antPathMatcher.match("/error", requestUrl)) {
            return SecurityConfig.createList("ROLE_normal");
        }

        // 查询数据库角色资源对应关系
        final List<RoleResourcesDto> roleResourcesDtos = roleResourcesMapper.getAll();
        // 过滤掉不匹配的路径
        final String[] strings = roleResourcesDtos.stream()
                .filter(roleResourcesDto -> antPathMatcher.match(roleResourcesDto.getResourceCode(), requestUrl))
                .map(roleResourcesDto -> "ROLE_" + roleResourcesDto.getRoleName()).collect(Collectors.toSet()).toArray(new String[]{});
        // 如果最后过滤到集合size == 0，则给一个默认的权限，不然会报错
        if (strings.length > 0){
            return SecurityConfig.createList(strings);
        }
        return SecurityConfig.createList("ROLE_normal");
    }

    /**
     *
     * 获取配置属性
     * @return 完整的角色资源集合
     */
    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return SecurityConfig.createList(roleResourcesMapper.getAll()
                .stream().map(roleResourcesDto -> "ROLE_" + roleResourcesDto.getRoleName())
                .collect(Collectors.toSet()).toArray(new String[]{}));
    }

    @Override
    public boolean supports(Class<?> aClass) {
        return FilterInvocation.class.isAssignableFrom(aClass);
    }

    /**
     * 角色资源mapper
     */
    private RoleResourcesMapper roleResourcesMapper;

    /**
     * 路径校验对象
     */
    private AntPathMatcher antPathMatcher;

    @Lazy
    @Autowired
    public void setAntPathMatcher(AntPathMatcher antPathMatcher){
        this.antPathMatcher = antPathMatcher;
    }

    @Autowired
    public void setRoleResourcesMapper(RoleResourcesMapper roleResourcesMapper){
        this.roleResourcesMapper = roleResourcesMapper;
    }
}
